package com.flying.io.objectstream;

import java.io.*;

/**
 * @author 刘鹏飞
 * @ClassName TestObjectStream
 * @Date 2025/2/24 22:17
 * @Created by 刘鹏飞
 * @Description
 *
 * TODO:
 *  序列化和反序列化是什么
 *  当两个进程远程通信时，彼此可以发送各种类型的数据。 无论是何种类型的数据，都会以二进制序列的形式在网络上传送。比如，我们可以通过http协议发送字符串信息；
 *  我们也可以在网络上直接发送Java对象。发送方需要把这个Java对象转换为字节序列，才能在网络上传送；接收方则需要把字节序列再恢复为Java对象才能正常读取。
 *  把Java对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的过程称为对象的反序列化。
 *  序列化涉及的类和接口
 *  ObjectOutputStream代表对象输出流，它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化，把得到的字节序列写到一个目标输出流中。
 *  ObjectInputStream代表对象输入流，它的readObject()方法从一个源输入流中读取字节序列，再把它们反序列化为一个对象，并将其返回。
 *  只有实现了Serializable接口的类的对象才能被序列化。 Serializable接口是一个空接口，只起到标记作用。
 *
 *
 *
 */
public class TestObjectStream {


    /**
     * ObjectInputStream 和 ObjectOutputStream 用于序列化与反序列化对象。
     *  处理流
     * 关键点：
     * 对象必须实现 Serializable 接口。
     * 使用 transient 关键字标记不需要序列化的字段
     * @param args
     */
    public static void main(String[] args) {


        try (   //  对象输出流
                ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("object.oc"));
                // 对象输入流
                ObjectInputStream ois=new ObjectInputStream(new FileInputStream("object.oc"))
        ) {
            // 操作基本数据类型对象

            oos.writeInt(10);
            oos.writeDouble(Math.random());
            oos.writeChar('a');
            oos.writeBoolean(true);
            oos.writeUTF("你好flying");
            oos.flush();


            // 写入自定义类型对象
            // 要求:
            // 对象所属类必须实现 Serializable 接口(标记接口,无抽象方法需要实现) ; 其成员变量也必须实现 Serializable
            // 使用 transient 关键字标记不需要序列化的字段

            Person person = new Person();
            person.setName("flying");
            person.setAge(21);
            person.setWordsToLife("快乐最重要,加油少年");

            // 写出文件
            oos.writeObject(person);

            oos.flush();




            // 读取对象
            // 必须按照写入的顺序读取
            System.out.println("int: "+ois.readInt());
            System.out.println("double: "+ois.readDouble());
            System.out.println("char: "+ois.readChar());
            System.out.println("boolean: "+ois.readBoolean());
            System.out.println("String: "+ois.readUTF());


            Person person1 = (Person)ois.readObject();
            System.out.println(person1);


        } catch (Exception e) {
            e.printStackTrace();
        }


    }


}
class Person implements Serializable{
    String name;
    int age;
    /*transient*/  String wordsToLife;  // 不需要序列化

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getWordsToLife() {
        return wordsToLife;
    }

    public void setWordsToLife(String wordsToLife) {
        this.wordsToLife = wordsToLife;
    }

    @Override
    public String toString() {
        return "Person{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", wordsToLife='" + wordsToLife + '\'' +
               '}';
    }
}
